iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Software Development

窮小子的售票系統系列 第 20

Day20: 實作-連接雲端資源 Part2

  • 分享至 

  • xImage
  •  

Cloud SQL 的連線設定完後還剩下 Memorystore for Redis 跟 Pub/Sub 一樣依序來進行配置

Memorystore for Redis

先前建立 Redis 時我們有多建立了一台 GCE 來進行連線的測試,我們可以再使用相同的指令來進行連線的測試

gcloud compute ssh [GCE_INSTANCE_NAME] --zone=[GCE_REGION] -- -N -L 6379:[REDIS_IP]:6379

https://ithelp.ithome.com.tw/upload/images/20240921/20168312aYG3tciqYc.png
在Windows 執行時會開啟一個 PuTTY 的視窗,此時就會將我們localhost:6379 post 的流量透過 GCE 轉導到 Redis。

Local Connect to Redis

接下來我們要透過程式碼來連線到 Redis

首先我們先安裝需要使用到的套件,.NET 環境有很多操作 Redis 的套件,依照個人使用習慣選擇就可以了,我這裡選了官方文件使用的 NRedisStack

dotnet add package NRedisStack

建立一個 Redis Service,新增 Service 資料夾在裡面建立 RedisService.cs

我們先寫兩個簡單的 Function 幫助我們做測試

using StackExchange.Redis;

namespace iThome2024.SalesService.Service;

public class RedisService
{
    private IDatabase _db;

    public RedisService(string connectionString)
    {
        ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(connectionString);
        _db = redis.GetDatabase();
    }
    public void StringSet(string key, string value)
    {
        _db.StringSet(key, value);
    }
    public string StringGet(string key)
    {
        return _db.StringGet(key).ToString();
    }
}

在 Minimal API 註冊 Service,我們這裡使用的 Connection String 一樣使用從 appsetting 取出來

builder.Services.AddSingleton<RedisService>(new RedisService(builder.Configuration.GetConnectionString("Redis")));

新增 API

app.MapPost("/Test/RedisAddString", (RedisService redisService, string key, string value) =>
{
    redisService.StringSet(key, value);
    return $"Set {key} to {value}";
})
.WithName("TestRedisAddString")
.WithOpenApi();

app.MapGet("/Test/RedisGetString", (string key, RedisService redisService) =>
{
    return redisService.StringGet(key).ToString();
})
.WithName("TestRedisGetString")
.WithOpenApi();

appsetting.json 新增連線資訊

https://ithelp.ithome.com.tw/upload/images/20240921/20168312xslf6FIrKy.png
測試一下

https://ithelp.ithome.com.tw/upload/images/20240921/20168312kJKXdM5FzF.png
OK 在 Local 連線到 Redis 連線就完成了。

Cloud Run Connect to Redis

把調整完畢的程式碼推送至 Github 讓 Cloud Build 自動幫我們上版,如果 appsetting.json 內沒有 Redis 的 ConnectionString 部屬可能會失敗,要先去 Secret Manager 建立一個 Redis ConnectionString 的 Secret ,記得密要值的 IP 要替換成 Redis 實際的 IP 而不是 localhost

https://ithelp.ithome.com.tw/upload/images/20240921/201683124yr64QgZU0.png
回到 Cloud Run 編輯一個新的版本把 RedisConnectstring 加上

https://ithelp.ithome.com.tw/upload/images/20240921/20168312SVxxK9UqxW.png
重新佈署後 Cloud Run 狀態就會是良好,我們再來測試一下

https://ithelp.ithome.com.tw/upload/images/20240921/20168312Zp4pt3JH3m.png
https://ithelp.ithome.com.tw/upload/images/20240921/20168312bx1g2ABAE7.png
OK 這樣 Redis 的連線也完成了

Pub/Sub

最後是我們的緩衝層 Message Service 服務 Pub/Sub。

Pub/Sub 是套 SaaS 服務,要跟他交互基本上就是使用 Google 官方提供的 SDK ,首先先把套件加入到我們的專案

dotnet add package Google.Cloud.PubSub.V1

Service 資料夾內新增 PublisherServiceSubscriberService

using Google.Cloud.PubSub.V1;

namespace iThome2024.SalesService.Service;

public class PublisherService
{
    private PublisherClient _publisher;

    public PublisherService(string projectId, string topicId)
    {
        TopicName topicName = new(projectId, topicId);
        _publisher = PublisherClient.Create(topicName);
    }
    public async Task<string> Publish(string message)
    {
        return await _publisher.PublishAsync(message);
    }
}
using Google.Cloud.PubSub.V1;

namespace iThome2024.SalesService.Service;

public class SubscriberService
{

    private SubscriptionName _subscriptionName;
    public SubscriberService(string projectId, string subscriptionId)
    {
        _subscriptionName = new(projectId, subscriptionId);

    }
    public async Task<List<string>> Subscribe()
    {
        var subscriber = await SubscriberClient.CreateAsync(_subscriptionName);
        List<string> receivedMessages = [];
        await subscriber.StartAsync((msg, cancellationToken) =>
        {
            receivedMessages.Add(msg.Data.ToStringUtf8());
            subscriber.StopAsync(TimeSpan.FromSeconds(15));
            return Task.FromResult(SubscriberClient.Reply.Ack);
        });
        return receivedMessages;
    }

}

註冊 Service

builder.Services.AddSingleton(
    new PublisherService(builder.Configuration["GoogleCloud:ProjectId"]!,
                         builder.Configuration["GoogleCloud:PubSub-Ticket:TopicId"]!));
builder.Services.AddSingleton(
    new SubscriberService(builder.Configuration["GoogleCloud:ProjectId"]!,
                          builder.Configuration["GoogleCloud:PubSub-Ticket:SubscriptionId"]!));

appsetting 新增 topic 相關設定

"GoogleCloud": {
    "ProjectId": "[Your Project Id]",
    "PubSub-Ticket": {
      "TopicId": "ithome-2024-topic",
      "SubscriptionId": "ithome-2024-topic-sub"
    }
  }

新增兩個測試用的 API

app.MapPost("/Test/PubSubPublishMessage", async (string message, PublisherService publisherService) =>
{
    return await publisherService.Publish(message);
})
.WithName("TestPubSubPublishMessage")
.WithOpenApi();

app.MapGet("/Test/PubSubSubscribeMessage", async (SubscriberService subscriberService) =>
{
    return await subscriberService.Subscribe();
})
.WithName("TestPubSubSubscribeMessage")
.WithOpenApi();

在 Local 測試看看

https://ithelp.ithome.com.tw/upload/images/20240921/20168312w9ZH0lzUAC.png
https://ithelp.ithome.com.tw/upload/images/20240921/20168312KSWnMofMlt.png
測試 OK 。

接下來推上 Cloud Run 就可以了,Pub/Sub 是 SaaS 服務原則上只要 Cloud Run 的 Service Account 權限有設置好就不需要做多餘的配置,Project Id 跟Topic Id 也不是機敏資訊通常不會需要存放到 Secret Manager。


上一篇
Day19: 實作-雲端資源建立-Secret Manager
下一篇
Day21: 實作-資源建立 Cloud Run-Process Service
系列文
窮小子的售票系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言